package com.hnas.core.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hnas.core.exception.CommonException;

public class PropertyUtil {
	private static final Logger log = LoggerFactory.getLogger(PropertyUtil.class);
	/**
	 * <pre>根据属性获取对应字段的值</pre> 
	 *@auther 周勇（zhou-y）
	 * 2013-8-29
	 * @param obj
	 * @param param
	 * @return
	 * @throws Exception
	 */
	public static Object getValue(Object obj, String param) throws Exception {
		if(null==obj)
			return "";
		Class c = obj.getClass();
		boolean hasChild = false;
		String para  = null;
		if(param.indexOf(".")>0){
			hasChild = true;
			int n = param.indexOf(".");
			para = param.substring(0,n);
			param = param.substring(n+1);
		}else{
			para  = param;
		}
		para  = "get" + para.substring(0, 1).toUpperCase()
				+ para.substring(1);
		Method m = null;
		try{
			m = c.getMethod(para, new Class[] {});
		}catch(NoSuchMethodException ex){
			para = para.replaceFirst("get", "is");
			m = c.getMethod(para, new Class[] {});
		}

		try {
			Object value = m.invoke(obj, new Object[] {});
			if (hasChild){
				if (null==value)
					return "";
				return getValue(value,param);//下一层
			}else{
				if (value instanceof Date){
					return DateUtil.dateToString((Date)value);
				}
				return value==null?"":value;
			}
		} catch (Exception e) {
			if (!(e instanceof InvocationTargetException)) {
				throw new Exception("获取参数出错！" + e);
			}
			throw new Exception(e.getCause().toString());
		}
	}
	public static void setValue(Object obj, String param, String value) throws CommonException {
		Class c = obj.getClass();
		param = "set" + param.substring(0, 1).toUpperCase()
				+ param.substring(1);
		Method m;
		try {
			m = c.getMethod(param, new Class[] {String.class});
		} catch (SecurityException e1) {
			// TODO Auto-generated catch block
//			e1.printStackTrace();
			throw new CommonException(e1);
		} catch (NoSuchMethodException e1) {
			// TODO Auto-generated catch block
//			e1.printStackTrace();
//			throw new CommonException(e1);
			return ;
		}
		try {
			m.invoke(obj, new Object[] {value});
//			return value;
		} catch (Exception e) {
			if (!(e instanceof InvocationTargetException)) {
				throw new CommonException("获取参数出错！" + e);
			}
			throw new CommonException(e.getCause().toString());
		}
	}
	
	/**
	 * <pre>比较两个类的相同属性的差异</pre> 
	 *@auther 周勇（zhou-y）
	 * 2013-9-4
	 * @param src
	 * @param target
	 * @return
	 */
	public static String compare(Object src, Object target) {
		try {
		
			StringBuffer sb = new StringBuffer();
			 Class klass = src.getClass();
			 Class c = target.getClass();
	          Method[] methods = klass.getMethods();
	          for (int i = 0; i < methods.length; i += 1) {
	              try {
	                  Method method = methods[i];
	                  String name = method.getName();
	                  if (name.equals("getClass"))
	                	  continue;
	                  if (!name.startsWith("get") && !name.startsWith("is"))
	                	  continue;
	                  Method m = c.getMethod(name, null);
	                  if (null==m)
	                	  continue;//同名方法
	                  //返回值类型不同
	                  if (null==m.getReturnType() || !m.getReturnType().equals(method.getReturnType()))
	                	  continue;
	                  if (m.getReturnType()==int.class || m.getReturnType()==Integer.class || m.getReturnType()==long.class || m.getReturnType()==Long.class|| m.getReturnType()==String.class || m.getReturnType()==boolean.class || m.getReturnType()==Boolean.class){
	                	  
	                  }else
	                	  continue;
                      Object v1 = avoidNull(method.invoke(src, null));
                      Object v2 = avoidNull(m.invoke(target, null));
                      if (v1.equals(v2))
                    	  continue;
	                  String key = "";
	                  if (name.startsWith("get")) {
	                      key = name.substring(3);
	                  } else if (name.startsWith("is")) {
	                      key = name.substring(2);
	                  }
	                  if (key.length() > 0 &&
	                          Character.isUpperCase(key.charAt(0)) &&
	                          method.getParameterTypes().length == 0) {
	                      if (key.length() == 1) {
	                          key = key.toLowerCase();
	                      } else if (!Character.isUpperCase(key.charAt(1))) {
	                          key = key.substring(0, 1).toLowerCase() +
	                              key.substring(1);
	                      }

	      					sb.append("; " + key + "：" + v1 + "-->"
	      							+ v2);
	                  }
	              } catch (Exception e) {
	                  /* forget about it */
	            	 log.error(e.getMessage(), e);
	              }
	          }

			if (sb.length() > 0)
				return sb.delete(0, 2).toString();
			else
				return "OK";
		} catch (Exception e) {
       	 log.error(e.getMessage(), e);
			
		}
		return "OK";
	}
	
	private static String avoidNull(Object s){
		if (null==s)
			return "";
		return s+"";
	}
}
